package me.ycy.android.shuffle.synchronizer
package ektorp

import scala.reflect.{ BeanInfo, BeanProperty }
import org.codehaus.jackson.annotate._
import org.codehaus.jackson.map.annotate._
import org.codehaus.jackson.map.{ JsonSerializer, JsonDeserializer,
                                  SerializerProvider, DeserializationContext }
import org.codehaus.jackson.{ JsonGenerator, JsonParser, JsonParseException, JsonLocation }

import java.util.Date

import JsonSubTypes.{Type => SubType }

@JsonTypeInfo(use      = JsonTypeInfo.Id.NAME,
              include  = JsonTypeInfo.As.PROPERTY,
              property = "type")
@JsonSubTypes(
  Array(new SubType(value = classOf[Task],    name = "task"),
        new SubType(value = classOf[Project], name = "project"),
        new SubType(value = classOf[Context], name = "context")))
sealed trait ShuffleItem
{
  var id: Long
  var revision: String
  var modifiedDate: Date
  var deleted: Boolean
  var active: Boolean

  @JsonProperty("_id") def getId = enc(id)
  @JsonProperty("_id") def setId(s: String) = { id = dec(s) }

  @JsonProperty("_rev") def getRevision = revision
  @JsonProperty("_rev") def setRevision(r: String) = { revision = r }

  def enc(id: Long): String = "%016x".format(id)
  def dec(id: String): Long = java.lang.Long.parseLong(id, 16)
}

case class Task (
  var id: Long,
  var revision: String,
  @BeanProperty var description: String,
  @BeanProperty var details: String,
  var projectId: Long,
  var contextId: Long,
  @BeanProperty var createdDate: Date,
  @BeanProperty var modifiedDate: Date,
  @BeanProperty var startDate: Date,
  @BeanProperty var dueDate: Date,
  @BeanProperty var timezone: String,
  @BeanProperty var calEventId: Long,
  @BeanProperty var displayOrder: Int,
  @BeanProperty var complete: Boolean,
  @BeanProperty var allDay: Boolean,
  @BeanProperty var hasAlarm: Boolean,
  @BeanProperty var deleted: Boolean,
  @BeanProperty var active: Boolean
) extends ShuffleItem {
  def this() = this(0, null,
                    null, null, 0, 0,
                    new Date(), new Date(), null, null,
                    "GMT", 0, 0, false, false, false,
                    false, false)

  @JsonProperty("contextId")
  def getContextId = enc(contextId)
  @JsonProperty("contextId")
  def setContentId(s: String) = { contextId = dec(s) }

  @JsonProperty("projectId")
  def setProjectId = enc(projectId)
  @JsonProperty("projectId")
  def getProjectId(s: String) = { projectId = dec(s) }
}

case class Project (
  var id: Long,
  var revision: String,
  @BeanProperty var name: String,
  var defaultContextId: Long,
  @BeanProperty var modifiedDate: Date,
  @BeanProperty var parallel: Boolean,
  @BeanProperty var archived: Boolean,
  @BeanProperty var deleted: Boolean,
  @BeanProperty var active: Boolean
) extends ShuffleItem {
  def this() = this(0, null,
                    null, 0, new Date(), false, false, false, false)

  @JsonProperty("defaultContextId")
  def getDefaultContextId = enc(defaultContextId)
  @JsonProperty("defaultContextId")
  def setDefaultContentId(s: String) = { defaultContextId = dec(s) }
}

case class Context (
  var id: Long,
  var revision: String,
  @BeanProperty var name: String,
  @BeanProperty var colour: Int,
  @BeanProperty var icon: String,
  @BeanProperty var modifiedDate: Date,
  @BeanProperty var deleted: Boolean,
  @BeanProperty var active: Boolean
) extends ShuffleItem {
  def this() = this(0, null,
                    null, 0, null, new Date(), false, false)

}

